#coding:utf-8
#包含脚本解析引擎
#from geventwebsocket import WebSocketError
import socket,threading
import re
import json
'''
class MessageServer(object):
    def __init__(self):
        self.observers = []#所有在线用户列表

    def _poll_to_all_user(self, msg):
        for ws in self.observers:
            try:
                ws.send(msg)
            except WebSocketError:
                self.observers.pop(self.observers.index(ws))#失败就从所有用户列表里删除
                print ws, 'is closed'
                continue
    def Return_To_User(self,usr,msg):
        usr.send(msg)#直接发送回去
'''
class Script(object):
    #类只有一个入口就是Return_，用于返回下一次代码的执行地址和本章节的所有静态资源如文本，图像，声音
    #Return收到用户进度flag传递给Resolve分析,FirstCS是入口点,ALL_CS是包含所有段内容和段标题
    #ALL_CS[段标题]=段内容，这样如果遇到goto的话就直接ALL_CS[GOTO地址]来返回段名
    def __init__(self,GameIO):
        #GameIO是自己的游戏脚本所在地址
        f = open(GameIO)
        self.GameIO = f
        self._FindAllCodeSegment()

    def Return_(self,flag):#返回
        #flag是用户保存的进度标识符
        self.flag = flag
        self.args = ["mov","goto","dwave","print","bgm","lsp","bgmstop","wait","textclear","bg","if","SEL","*","end","fin","gosub","br","ld","delay","stop"]
        if self.flag["cs"]=="":
            #是刚启动游戏，返回入口点地址
            print ("first:",self.FiestCS)
            self.__Resolve(_txt("*","\n",self.FiestCS))
        else:
            self.__Resolve(self.flag["cs"])
            self.flag.pop("cs")
        self.flag
        return json.dumps({"flags":self.flag,"bg":self.Ret_bg,"bgm":self.Ret_bgm,"str":self.Ret_str,"Dwave":self.Ret_Dwave,"Next":self.Next_cs,"ld":self.ld})

    def _decodeFlag(self,flag):
        #暂定，因为flag是dict，所以应该不用解码了
        pass

    def __Resolve(self,CS):#开始分析
        for i in self.All_CS:
            print ("all:",i)
        Code = self.All_CS[CS]
        self.Ret_bg = {}
        self.Tmp_str = ""
        self.Ret_str = []
        self.ld = {}
        self.Ret_Dwave = {}
        self.Ret_bgm = {}
        self.Next_cs = self.__poll(Code)
        if self.Next_cs == "error":
            #得向前端抛出错误
            return
        #Return bgm,str,dwave,bg,next_cs
        #因为还没和前端约定好所以就先不return了
        #print (self.Ret_str,"Next:",Next_cs)
    def __poll(self,Code):
        print Code
        #为了跳出多层循环不得不这样子弄
        iscode = len(self.args)#重构计数器，很重要
        for d in Code.split('\n'):
            #每行加载文件
            for i in self.args:
                if d.find(i) != -1:#只判断前9个字符
                    #print("IsCode:",i)
                    #指令分析
                    if i == "goto" and d[:4] == i:
                        try:
                            d = d.split(" ")
                            iscode = len(self.args)
                            return d[1] #为了跳出多层循环
                        except:
                            print "ERROR:",Code
                            return "error"
                    if i == "bg" and d[:2] == i:
                        try:
                            d = d.split(" ")
                            self.Ret_bg[len(self.Ret_str)]=_txt('"','"',d[1])
                        except:
                            print "ERROR:",Code
                        iscode = len(self.args)
                        break
                    if i == "dwave" and d[:5] ==i:
                        try:
                            d = d.split(" ")
                            self.Ret_Dwave[len(self.Ret_str)] = _txt('"','"',d[1])
                        except:
                            print "ERROR:",Code
                        iscode = len(self.args)
                        break
                    if i == "bgm" and d[:3] == i:
                        try:
                            d = d.split(" ")
                            self.Ret_bgm[len(self.Ret_str)] = _txt('"','"',d[1])
                        except:
                            print "ERROR:",Code
                        iscode = len(self.args)
                        break
                    if i == "if" and d[:2]==i:
                        try:
                            iscode = len(self.args)
                            d = d.split(" ")
                            iif = d[1].split("==")
                            if iif[0] in self.flag:
                                if iif[1] == self.flag[iif[0]]:#判断是否为真
                                    if d[2] == "goto":#应该分析很多很多语法的，然而为了测试我只写了gooto
                                        return d[3]
                                else:#条件不符合，继续执行下面的代码
                                    break
                            break
                        except:
                            print "ERROR:",Code
                            return "error"
                    if i =="end" and d[:3]==i:
                        iscode = len(self.args)
                        #既然有end了那么就是脚本逻辑错误了，因为一般执行在end之前都goto走了，所以返回个错误
                        #这里待定，考虑到底要不要忽略
                        return "error"
                    if i =="fin"and d[:3] ==i:
                        iscode = len(self.args)
                        #游戏结束
                        return "GameEnd"
                    if i=="SEL"and d[:3]==i:#要改！！！！！！应该吧
                        iscode = len(self.args)
                        return d#选择支嘛，交给前端处理咯
                    if i=="mov" and d[:3]==i:
                        try:
                            iscode = len(self.args)
                            d = d.split(" ")
                            p = d[1].split(",")
                            self.flag[p[0]] = p[1]
                        except:
                            print "ERROR:",Code
                        break
                    if i=="ld" and d[:2]==i:
                        try:
                            iscode = len(self.args)
                            d = d.split(" ")
                            self.ld[len(self.Ret_str)]= _txt(";",'"',d[1])
                        except:
                            print "ERROR:",Code
                        break




                else:
                    iscode -= 1
            if iscode == 0:
                #真TMD不是代码
                try:
                    self.Tmp_str = self.Tmp_str + d+'\n'
                    if d[-1:] == "\\":
                        self.Ret_str.append(self.Tmp_str.replace("\\",""))
                        self.Tmp_str = ""
                        iscode = len(self.args)
                        continue
                except:
                    print "ERROR:",Code
                    continue
                iscode = len(self.args)
            iscode = len(self.args)
    def _FindAllCodeSegment(self):
        #匿名函数，外部最好不使用
        #放置入口点以及加载代码段
        All_CS = {}
        all = re.findall('(\*.*?end\n)',self.GameIO.read(),re.S)
        self.FiestCS = all[0]
        for i in all:
            title = _txt("*","\n",i)
            print("title:",title)
            All_CS[title] = i
        self.All_CS = All_CS

def _decodeJsonToDict(jso_n):
    my_dict={}
    for i in jso_n["flag"]:
        my_dict[i]=jso_n["flag"][i]
    my_dict["cs"]=jso_n["cs"]
    return my_dict


def _txt(start_str, end, html):
    #获取两个字符串中间的内容
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()
